package com.bosssoft.cloud.wechat.core.controller;

import com.bosssoft.cloud.wechat.core.bean.param.portal.WxMsgParam;
import com.bosssoft.cloud.wechat.core.infra.config.WxConfig;
import com.bosssoft.cloud.wechat.core.infra.util.WxSignatureUtil;
import com.bosssoft.cloud.wechat.core.router.WxCoreRouter;
import com.bosssoft.cloud.wechat.infrastructure.util.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

/**
 * 微信控制器
 * 开发者验证，接收微信推送消息
 * <p>
 * http://localhost:80/wechat-common/wx/portal/{APPID}
 *
 * @author wcy create on 2021/5/26 11:56 上午
 */
@Slf4j
@RestController
@RequestMapping("portal/{appid}")
public class WxPortalController {

    @Resource
    private WxConfig wxConfig;

    @Autowired
    private WxCoreRouter wxCoreRouter;

    /**
     * 进行开发者验证，接入微信。
     * GET请求
     *
     * @param signature 微信加密签名，signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @param echostr   随机字符串
     * @return 验证通过，原样返回echostr字符串
     */
    @GetMapping(produces = "text/plain;charset=utf-8")
    public String authGet(@RequestParam(value = "signature") String signature,
                          @RequestParam(value = "timestamp") String timestamp,
                          @RequestParam(value = "nonce") String nonce,
                          @RequestParam(value = "echostr") String echostr) {
        /*
        认证逻辑
         */
        if (!WxSignatureUtil.checkSignature(wxConfig.getMpConfig().getMpToken(), signature, timestamp, nonce)) {
            log.warn("不是微信服务器发过来的请求，请小心！");
            return null;
        }
        // 此处也可添加财政公众号专有的认证逻辑（可选）
        log.info("微信签名验证成功!");
        return echostr;
    }

    /**
     * 开发者验证外的请求都是post
     * 做接收消息，事件推送等与公众号的日常交互
     * <p>
     * 目前未处理xmlStr外的信息，但都有用，包括二次校验，加密解密，记录访问等。勿删
     *
     * @param appid        appid
     * @param signature    微信加密签名
     * @param timestamp    时间戳
     * @param nonce        随机数
     * @param openid       微信用户在公众号appid下的唯一用户标识(appid不同,则获取到的openid就不同)
     * @param encType      加密类型，aes，null(明文)等
     * @param msgSignature * 加密签名
     * @param xmlStr       请求xml
     * @return 返回消息
     */
    @PostMapping(produces = {"application/xml;charset=utf-8"})
    public String post(@PathVariable String appid,
                       @RequestParam("signature") String signature,
                       @RequestParam("timestamp") String timestamp,
                       @RequestParam("nonce") String nonce,
                       @RequestParam("openid") String openid,
                       @RequestParam(name = "encrypt_type", required = false) String encType,
                       @RequestParam(name = "msg_signature", required = false) String msgSignature,
                       @RequestBody String xmlStr,
                       HttpSession session
    ) {
        // xml解析
        WxMsgParam param = XmlUtil.toObj(xmlStr, WxMsgParam.class); //JSON.parseObject(json, WxMsgParam.class);
        // 在此处可预处理，（可选）
        // 如：记录访问用户，加密解密等
        return wxCoreRouter.route(param, session);
    }
}
